<template>
  <div>
    <div class="mgb20">
      <el-button type="primary" @click="handleDialogShowUser('add')">新建用户</el-button>
    </div>

    <base-table
      :pagination="pagination"
      :table="table"
      @sortChange="handleSortChange"
      @expandChange="handleExpandChange"
      @sizeChange="handlePaging"
      @currentChange="handlePaging"
    >
      <template #typeColumn>
        <el-table-column type="index" :index="rowIndex" width="60" label="序号" align="center"></el-table-column>
      </template>
      <template #operationColumn>
        <el-table-column type="expand" width="60">
          <template #header> 详情 </template>
          <template #default="{row}">
            <p v-for="(value, key) in row" :key="key">
              <span class="expanded-item-label">{{ key }}：</span>
              <span>{{ value }}</span>
            </p>
          </template>
        </el-table-column>
        <el-table-column label="操作" :min-width="100" align="center">
          <template #default="{row}">
            <el-button
              type="primary"
              size="small"
              :disabled="row.username === 'admin'"
              @click="handleDialogShowUser('edit', row)"
            >
              编辑
            </el-button>
            <el-button
              type="danger"
              size="small"
              :disabled="row.username === 'admin'"
              @click="handleDialogShowConfirm('delete', row)"
            >
              删除
            </el-button>
          </template>
        </el-table-column>
      </template>
    </base-table>

    <!--添加/编辑用户-->
    <base-dialog
      ref="dialogUser"
      :title="`${dialog.user.type === 'edit' ? '编辑' : '新增'}用户`"
      :dialogId="dialog.user.dialogId"
      @dialogConfirm="handleDialogUserSubmit"
      @dialogClose="dialog.user.dialogId = 0"
    >
      <el-form :model="formData" :rules="formRules" ref="userForm" label-width="80px">
        <el-form-item label="用户名" prop="username">
          <el-input
            maxlength="20"
            placeholder="请输入用户名"
            v-model.trim="formData.username"
            clearable
            :disabled="dialog.user.type === 'edit'"
            onpaste="return false"
          >
          </el-input>
        </el-form-item>
        <el-form-item label="密码" prop="password" :required="isPasswordRequired">
          <el-input
            v-if="dialog.user.type === 'add' || isResetPassword"
            maxlength="20"
            type="password"
            placeholder="请输入密码"
            v-model.trim="formData.password"
            clearable
            onpaste="return false"
          >
          </el-input>
          <el-button v-else @click="isResetPassword = true">重置</el-button>
        </el-form-item>
        <el-form-item v-if="dialog.user.type === 'add' || isResetPassword" label="确认密码" prop="repeatPassword">
          <el-input
            maxlength="20"
            type="password"
            placeholder="请再次输入密码"
            v-model.trim="formData.repeatPassword"
            clearable
            onpaste="return false"
          >
          </el-input>
        </el-form-item>
        <el-form-item label="用户类型">
          <el-tag>普通用户</el-tag>
        </el-form-item>
        <el-form-item label="描述" prop="origin">
          <el-input type="textarea" maxlength="250" placeholder="请输入描述" v-model.trim="formData.description"> </el-input>
        </el-form-item>
      </el-form>
    </base-dialog>

    <!--弹框-->
    <base-dialog
      ref="dialogConfirm"
      :title="dialog.confirm.title"
      :dialogId="dialog.confirm.dialogId"
      @dialogConfirm="handleDialogConfirmSubmit"
      @dialogClose="dialog.confirm.dialogId = 0"
    >
      <p class="base-dialog-tooltip">{{ dialog.confirm.tooltip }}</p>
    </base-dialog>
  </div>
</template>

<script setup>
  import useTable from '@/composables/useTable';
  import SHA256 from 'js-sha256';
  import {reactive, ref, getCurrentInstance, onMounted, computed} from 'vue';

  const {proxy} = getCurrentInstance();
  const {
    table,
    pagination,
    rowIndex,
    setTableData,
    getTableRequestParams,
    refreshTableData,
    handleSortChange,
    handlePaging,
    handleVisibleColumnsChange,
    handleExpandChange
  } = useTable(proxy);
  const userFormDefault = {
    id: '',
    username: '',
    password: '',
    repeatPassword: '',
    role: '普通用户',
    description: ''
  };
  Object.assign(table, {
    defaultSort: {prop: 'created', order: 'descending'},
    columns: [
      {label: '创建时间', prop: 'created', filter: 'formatDate', arguments: [], width: 150, sortable: true},
      {label: '用户名', prop: 'username', sortable: true},
      {label: '用户类型', prop: 'role', align: 'center'},
      {label: '描述', prop: 'description'},
      {label: '最近登录时间', prop: 'lastLogin', filter: 'formatDate', arguments: [], width: 150}
    ]
  });
  let isResetPassword = ref(false);
  const dialog = reactive({
    user: {
      dialogId: 0,
      type: 'add'
    },
    confirm: {
      dialogId: 0,
      title: '',
      tooltip: '',
      params: []
    }
  });
  const formData = reactive({...userFormDefault});
  const formRules = reactive({
    username: [{required: true, validator: proxy.$validator.username, isEdit: false, fieldType: '用户名'}],
    password: [
      {
        trigger: 'change',
        validator: (rule, value, callback) => {
          // 避免清除表单项后，错误提示是英文
          isPasswordRequired.value && !value ? callback(new Error('请输入密码')) : callback();
        }
      },
      {
        trigger: 'blur',
        fieldType: '密码',
        validator: (rule, value, callback) => {
          rule.required = isPasswordRequired.value;
          proxy.$validator.password(rule, value, callback);
        }
      }
    ],
    repeatPassword: [
      {
        required: true,
        trigger: 'blur',
        fieldType: '确认密码',
        validator: (rule, value, callback) => {
          rule.newPassword = formData.password;
          proxy.$validator.password(rule, value, callback);
        }
      }
    ]
  });
  const isPasswordRequired = computed(() => !(formData.id && !isResetPassword.value));
  const getTableData = () => {
    setTableData('systemManage', 'getUser', getTableRequestParams());
  };
  // type: add/edit
  const handleDialogShowUser = (type, row) => {
    isResetPassword.value = false;
    if (proxy.$refs.userForm !== undefined) {
      proxy.$refs.userForm.resetFields();
    }
    Object.assign(formData, userFormDefault);
    if (type === 'edit') {
      proxy.$tool.setObject(formData, row);
      formData.password = '';
    }
    dialog.user.type = type;
    formRules.username[0].isEdit = dialog.user.type === 'edit';
    dialog.user.dialogId = Date.now();
  };
  // type: delete
  const handleDialogShowConfirm = (type, row) => {
    Object.assign(dialog.confirm, {
      dialogId: Date.now(),
      title: '确认删除',
      tooltip: '确认删除该用户？',
      params: row.id
    });
  };
  const handleDialogConfirmSubmit = async () => {
    proxy.$refs.dialogConfirm.loadingOpen();
    const res = await proxy.$api.systemManage.delUser(dialog.confirm.params);
    proxy.$refs.dialogConfirm.loadingClose();
    if (!!res && res.status === 200) {
      dialog.confirm.dialogId = 0;
      proxy.$message.success('删除用户成功');
      refreshTableData();
    } else {
      proxy.$message.error(res.message);
    }
  };
  const handleDialogUserSubmit = () => {
    proxy.$refs.userForm.validate(async valid => {
      if (!valid) return;
      proxy.$refs.dialogUser.loadingOpen();
      const params = {
        username: formData.username,
        role: formData.role,
        description: formData.description,
        id: dialog.user.type === 'add' ? '' : formData.id
      };
      if (isPasswordRequired.value) {
        params.password = SHA256.hmac(formData.username, formData.password);
      }
      const res = await proxy.$api.systemManage[dialog.user.type === 'edit' ? 'editUser' : 'addUser'](params);
      proxy.$refs.dialogUser.loadingClose();
      if (!!res && res.status === 200) {
        dialog.user.dialogId = 0;
        proxy.$message.success(dialog.user.type === 'edit' ? '编辑用户成功' : '新增用户成功');
        refreshTableData();
      } else {
        proxy.$message.error(res.message);
      }
    });
  };
  onMounted(getTableData);
</script>
